package cn.antcore.common.exception;

import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.resource.NoResourceFoundException;

import java.util.stream.Collectors;

/**
 * 全局异常处理
 * <br>
 * Created by Hong 2024/5/28
**/
@Resource
@RestController
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(Exception.class)
    public ReturnT exceptionHandler(Exception exception) {
        log.error(exception.toString(), exception);
        if (exception instanceof AppException appException) {
            return ReturnT.fail(new ErrorCode(appException.getCode(), appException.getMessage()));
        } else if (exception instanceof HttpRequestMethodNotSupportedException) {
            return ReturnT.fail(ErrorCode.PAGES_405_ERROR);
        } else if (exception instanceof BindException) {
            return ReturnT.fail(new ErrorCode(ErrorCode.PAGES_400_ERROR, ((BindException) exception).getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(", "))));
        } else if (exception instanceof MethodArgumentTypeMismatchException || exception instanceof MissingServletRequestParameterException) {
            return ReturnT.fail(new ErrorCode(ErrorCode.PAGES_400_ERROR, exception.toString()));
        } else if (exception instanceof AccessDeniedException) {
            return ReturnT.fail(ErrorCode.PAGES_401_ERROR);
        } else if (exception instanceof NoResourceFoundException) {
            return ReturnT.fail(ErrorCode.PAGES_404_ERROR);
        } else {
            return ReturnT.fail(ErrorCode.ERROR);
        }
    }
}
